\subsection{\TT{X\$KSMLRU} table in \oracle}
\myindex{\oracle}

There is a mention of a special table in the \IT{Diagnosing and Resolving Error ORA-04031 
on the Shared Pool or Other Memory Pools [Video] [ID 146599.1]} note:

\begin{framed}
\begin{quotation}
There is a fixed table called X\$KSMLRU that tracks allocations in the shared pool that cause other objects 
in the shared pool to be aged out. This fixed table can be used to identify what is causing the large allocation.

If many objects are being periodically flushed from the shared pool then this will cause response time problems 
and will likely cause library cache latch contention problems when the objects are reloaded into the shared pool.

One unusual thing about the X\$KSMLRU fixed table is that the contents of the fixed table are erased whenever 
someone selects from the fixed table. This is done since the fixed table stores only the largest allocations 
that have occurred. The values are reset after being selected so that subsequent large allocations can be noted 
even if they were not quite as large as others that occurred previously. Because of this resetting, the output 
of selecting from this table should be carefully kept since it cannot be retrieved back after the query is issued.
\end{quotation}
\end{framed}

However, as it can be easily checked, the contents of this table are cleared each time it's queried.
Are we able to find why?
Let's get back to tables we already know: \TT{kqftab} and \TT{kqftap} 
which were generated with \oracletables's help, that has all information about the X\$-tables. We can see here 
that the \TT{ksmlrs()} function is called to prepare this table's elements:

\begin{lstlisting}[caption=Result of \OracleTablesName]
kqftab_element.name: [X$KSMLRU] ?: [ksmlr] 0x4 0x64 0x11 0xc 0xffffc0bb 0x5
kqftap_param.name=[ADDR] ?: 0x917 0x0 0x0 0x0 0x4 0x0 0x0
kqftap_param.name=[INDX] ?: 0xb02 0x0 0x0 0x0 0x4 0x0 0x0
kqftap_param.name=[INST_ID] ?: 0xb02 0x0 0x0 0x0 0x4 0x0 0x0
kqftap_param.name=[KSMLRIDX] ?: 0xb02 0x0 0x0 0x0 0x4 0x0 0x0
kqftap_param.name=[KSMLRDUR] ?: 0xb02 0x0 0x0 0x0 0x4 0x4 0x0
kqftap_param.name=[KSMLRSHRPOOL] ?: 0xb02 0x0 0x0 0x0 0x4 0x8 0x0
kqftap_param.name=[KSMLRCOM] ?: 0x501 0x0 0x0 0x0 0x14 0xc 0x0
kqftap_param.name=[KSMLRSIZ] ?: 0x2 0x0 0x0 0x0 0x4 0x20 0x0
kqftap_param.name=[KSMLRNUM] ?: 0x2 0x0 0x0 0x0 0x4 0x24 0x0
kqftap_param.name=[KSMLRHON] ?: 0x501 0x0 0x0 0x0 0x20 0x28 0x0
kqftap_param.name=[KSMLROHV] ?: 0xb02 0x0 0x0 0x0 0x4 0x48 0x0
kqftap_param.name=[KSMLRSES] ?: 0x17 0x0 0x0 0x0 0x4 0x4c 0x0
kqftap_param.name=[KSMLRADU] ?: 0x2 0x0 0x0 0x0 0x4 0x50 0x0
kqftap_param.name=[KSMLRNID] ?: 0x2 0x0 0x0 0x0 0x4 0x54 0x0
kqftap_param.name=[KSMLRNSD] ?: 0x2 0x0 0x0 0x0 0x4 0x58 0x0
kqftap_param.name=[KSMLRNCD] ?: 0x2 0x0 0x0 0x0 0x4 0x5c 0x0
kqftap_param.name=[KSMLRNED] ?: 0x2 0x0 0x0 0x0 0x4 0x60 0x0
kqftap_element.fn1=ksmlrs
kqftap_element.fn2=NULL
\end{lstlisting}

\myindex{tracer}
Indeed, with \tracer's help it is easy to see that this function is called each 
time we query the \TT{X\$KSMLRU} table.

\myindex{\CStandardLibrary!memset()}
Here we see a references to the \TT{ksmsplu\_sp()} and \TT{ksmsplu\_jp()} functions, each of 
them calls the \TT{ksmsplu()} at the end.
At the end of the \TT{ksmsplu()} function we see 
a call to \TT{memset()}:

\begin{lstlisting}[caption=ksm.o,style=customasmx86]
...

.text:00434C50 loc_434C50:    ; DATA XREF: .rdata:off_5E50EA8
.text:00434C50         mov     edx, [ebp-4]
.text:00434C53         mov     [eax], esi
.text:00434C55         mov     esi, [edi]
.text:00434C57         mov     [eax+4], esi
.text:00434C5A         mov     [edi], eax
.text:00434C5C         add     edx, 1
.text:00434C5F         mov     [ebp-4], edx
.text:00434C62         jnz     loc_434B7D
.text:00434C68         mov     ecx, [ebp+14h]
.text:00434C6B         mov     ebx, [ebp-10h]
.text:00434C6E         mov     esi, [ebp-0Ch]
.text:00434C71         mov     edi, [ebp-8]
.text:00434C74         lea     eax, [ecx+8Ch]
.text:00434C7A         push    370h            ; Size
.text:00434C7F         push    0               ; Val
.text:00434C81         push    eax             ; Dst
.text:00434C82         call    __intel_fast_memset
.text:00434C87         add     esp, 0Ch
.text:00434C8A         mov     esp, ebp
.text:00434C8C         pop     ebp
.text:00434C8D         retn
.text:00434C8D _ksmsplu  endp
\end{lstlisting}

Constructions like \TT{memset (block, 0, size)} are often used just to zero memory block.
What if we take a risk, block the \TT{memset()} call and see what happens?

\myindex{tracer}

Let's run \tracer with the following options: set breakpoint at \TT{0x434C7A} 
(the point where the arguments to \TT{memset()} are to be passed), 
so that \tracer will set program counter \TT{EIP} to the point where the arguments passed to \TT{memset()} are to be cleared (at \TT{0x434C8A})
It can be said that we just simulate an unconditional jump from address \TT{0x434C7A} to \TT{0x434C8A}.

\begin{lstlisting}
tracer -a:oracle.exe bpx=oracle.exe!0x00434C7A,set(eip,0x00434C8A)
\end{lstlisting}

(Important: all these addresses are valid only for the win32 version of \oracle 11.2)

Indeed, now we can query the \TT{X\$KSMLRU} table as many times as we want and it is not being cleared anymore!

\sout{Do not try this at home ("MythBusters")} Do not try this on your production servers.

It is probably not a very useful or desired system behavior, but as an experiment for locating a piece of code that we need, it perfectly suits our needs!

